package com.xyingsoft.zp.zP_Board.manager;

import org.bukkit.Bukkit;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextColor;
import net.kyori.adventure.text.format.TextDecoration;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.scoreboard.*;

import java.util.*;
import java.util.stream.Collectors;

public class ScoreboardManager {
    private final Plugin plugin;
    private final DataManager dataManager;
    private final FileConfiguration config;
    
    // 用于跟踪当前显示的计分板类型
    private int currentBoardType = 0;
    private List<Integer> enabledBoards = new ArrayList<>();
    
    // 颜色序列，用于美化计分板
    private static final NamedTextColor[] COLORS = {
            NamedTextColor.RED, NamedTextColor.GOLD, NamedTextColor.YELLOW, 
            NamedTextColor.GREEN, NamedTextColor.AQUA, NamedTextColor.LIGHT_PURPLE
    };
    
    // 边框字符，用于美化计分板
    private static final String[] BORDERS = {
            "✦", "❉", "✿", "❀", "✹", "✯", "✡", "❂", "⚝"
    };
    
    // 自定义方法重复字符串
    private String repeatString(String str, int count) {
        StringBuilder result = new StringBuilder();
        for (int i = 0; i < count; i++) {
            result.append(str);
        }
        return result.toString();
    }
    
    public ScoreboardManager(Plugin plugin, DataManager dataManager) {
        this.plugin = plugin;
        this.dataManager = dataManager;
        this.config = plugin.getConfig();
        
        // 初始化启用的计分板类型
        initEnabledBoardTypes();
        
        // 设置计分板切换间隔
        int switchInterval = config.getInt("scoreboard.switch_interval", 10);
        Bukkit.getScheduler().runTaskTimer(plugin, this::switchBoardType, 
            switchInterval * 20L, switchInterval * 20L);
        
        // 每分钟更新一次在线时间
        int onlineTimeInterval = config.getInt("data.online_time_update_interval", 1);
        Bukkit.getScheduler().runTaskTimer(plugin, this::updateOnlineTime, 
            onlineTimeInterval * 1200L, onlineTimeInterval * 1200L);
        
        // 每5秒更新一次计分板
        Bukkit.getScheduler().runTaskTimer(plugin, this::updateScoreboards, 100L, 100L);
    }
    
    private void initEnabledBoardTypes() {
        if (config.getBoolean("scoreboard.enable_online_time", true)) {
            enabledBoards.add(0);
        }
        if (config.getBoolean("scoreboard.enable_blocks_break", true)) {
            enabledBoards.add(1);
        }
        if (config.getBoolean("scoreboard.enable_kills", true)) {
            enabledBoards.add(2);
        }
        if (config.getBoolean("scoreboard.enable_deaths", true)) {
            enabledBoards.add(3);
        }
        if (config.getBoolean("scoreboard.enable_experience", true)) {
            enabledBoards.add(4);
        }
        
        // 如果没有启用任何计分板，默认启用在线时间排行榜
        if (enabledBoards.isEmpty()) {
            enabledBoards.add(0);
        }
    }
    
    private void switchBoardType() {
        if (enabledBoards.isEmpty()) return;
        
        // 找到当前计分板类型在启用列表中的索引
        int currentIndex = enabledBoards.indexOf(currentBoardType);
        
        // 如果当前类型不在启用列表中，或者是最后一个，则切换到第一个
        if (currentIndex == -1 || currentIndex == enabledBoards.size() - 1) {
            currentBoardType = enabledBoards.get(0);
        } else {
            // 否则切换到下一个
            currentBoardType = enabledBoards.get(currentIndex + 1);
        }
        
        updateScoreboards();
    }
    
    private void updateOnlineTime() {
        for (Player player : Bukkit.getOnlinePlayers()) {
            PlayerData data = dataManager.getPlayerData(player);
            data.incrementOnlineTime();
        }
    }
    
    public void updateScoreboards() {
        for (Player player : Bukkit.getOnlinePlayers()) {
            updateScoreboard(player);
        }
    }
    
    public void updateScoreboard(Player player) {
        switch (currentBoardType) {
            case 0:
                setOnlineTimeBoard(player);
                break;
            case 1:
                setBlocksBreakBoard(player);
                break;
            case 2:
                setKillsBoard(player);
                break;
            case 3:
                setDeathsBoard(player);
                break;
            case 4:
                setExperienceBoard(player);
                break;
        }
    }
    
    // 在线时长排行榜
    private void setOnlineTimeBoard(Player player) {
        Scoreboard scoreboard = Bukkit.getScoreboardManager().getNewScoreboard();
        Objective objective = scoreboard.registerNewObjective("onlineTime", Criteria.DUMMY, 
            Component.text(config.getString("scoreboard.titles.online_time", "在线时长排行")));
        objective.setDisplaySlot(DisplaySlot.SIDEBAR);
        
        int displayPlayers = config.getInt("scoreboard.display_players", 10);
        List<Map.Entry<UUID, PlayerData>> sortedPlayers = dataManager.getAllPlayerData().entrySet().stream()
                .sorted(Map.Entry.<UUID, PlayerData>comparingByValue(Comparator.comparing(PlayerData::getOnlineTime)).reversed())
                .limit(displayPlayers)
                .collect(Collectors.toList());
        
        // 添加装饰边框
        Score topBorder = objective.getScore(getRandomBorder());
        topBorder.setScore(displayPlayers + 1);
        
        // 添加排行数据
        int scoreValue = displayPlayers;
        for (int i = 0; i < sortedPlayers.size(); i++) {
            Map.Entry<UUID, PlayerData> entry = sortedPlayers.get(i);
            PlayerData data = entry.getValue();
            UUID uuid = entry.getKey();
            
            String playerName = Bukkit.getOfflinePlayer(uuid).getName();
            if (playerName == null) playerName = "未知玩家";
            
            int hours = data.getOnlineTime() / 60;
            int minutes = data.getOnlineTime() % 60;
            
            String displayText = getEntryColorCode(i) + (i + 1) + ". " + playerName + ": " + hours + "小时" + minutes + "分钟";
            // 确保不会超过40个字符（Minecraft计分板限制）
            if (displayText.length() > 40) {
                displayText = displayText.substring(0, 37) + "...";
            }
            
            Score score = objective.getScore(displayText);
            score.setScore(scoreValue--);
        }
        
        // 填充空行，确保至少有displayPlayers个条目
        while (scoreValue > 1) {
            Score emptyScore = objective.getScore(repeatString(" ", scoreValue));
            emptyScore.setScore(scoreValue--);
        }
        
        // 添加底部边框
        Score bottomBorder = objective.getScore(getRandomBorder());
        bottomBorder.setScore(0);
        
        player.setScoreboard(scoreboard);
    }
    
    // 挖掘方块排行榜
    private void setBlocksBreakBoard(Player player) {
        Scoreboard scoreboard = Bukkit.getScoreboardManager().getNewScoreboard();
        Objective objective = scoreboard.registerNewObjective("blocksBreak", Criteria.DUMMY, 
            Component.text(config.getString("scoreboard.titles.blocks_break", "挖掘榜")));
        objective.setDisplaySlot(DisplaySlot.SIDEBAR);
        
        int displayPlayers = config.getInt("scoreboard.display_players", 10);
        List<Map.Entry<UUID, PlayerData>> sortedPlayers = dataManager.getAllPlayerData().entrySet().stream()
                .sorted(Map.Entry.<UUID, PlayerData>comparingByValue(Comparator.comparing(PlayerData::getBlocksBreak)).reversed())
                .limit(displayPlayers)
                .collect(Collectors.toList());
        
        // 添加装饰边框
        Score topBorder = objective.getScore(getRandomBorder());
        topBorder.setScore(displayPlayers + 1);
        
        // 添加排行数据
        int scoreValue = displayPlayers;
        for (int i = 0; i < sortedPlayers.size(); i++) {
            Map.Entry<UUID, PlayerData> entry = sortedPlayers.get(i);
            PlayerData data = entry.getValue();
            UUID uuid = entry.getKey();
            
            String playerName = Bukkit.getOfflinePlayer(uuid).getName();
            if (playerName == null) playerName = "未知玩家";
            
            String displayText = getEntryColorCode(i) + (i + 1) + ". " + playerName + ": " + data.getBlocksBreak() + "方块";
            if (displayText.length() > 40) {
                displayText = displayText.substring(0, 37) + "...";
            }
            
            Score score = objective.getScore(displayText);
            score.setScore(scoreValue--);
        }
        
        // 填充空行
        while (scoreValue > 1) {
            Score emptyScore = objective.getScore(repeatString(" ", scoreValue));
            emptyScore.setScore(scoreValue--);
        }
        
        // 添加底部边框
        Score bottomBorder = objective.getScore(getRandomBorder());
        bottomBorder.setScore(0);
        
        player.setScoreboard(scoreboard);
    }
    
    // 击杀排行榜
    private void setKillsBoard(Player player) {
        Scoreboard scoreboard = Bukkit.getScoreboardManager().getNewScoreboard();
        Objective objective = scoreboard.registerNewObjective("kills", Criteria.DUMMY, 
            Component.text(config.getString("scoreboard.titles.kills", "击杀榜")));
        objective.setDisplaySlot(DisplaySlot.SIDEBAR);
        
        int displayPlayers = config.getInt("scoreboard.display_players", 10);
        List<Map.Entry<UUID, PlayerData>> sortedPlayers = dataManager.getAllPlayerData().entrySet().stream()
                .sorted(Map.Entry.<UUID, PlayerData>comparingByValue(Comparator.comparing(PlayerData::getKills)).reversed())
                .limit(displayPlayers)
                .collect(Collectors.toList());
        
        // 添加装饰边框
        Score topBorder = objective.getScore(getRandomBorder());
        topBorder.setScore(displayPlayers + 1);
        
        // 添加排行数据
        int scoreValue = displayPlayers;
        for (int i = 0; i < sortedPlayers.size(); i++) {
            Map.Entry<UUID, PlayerData> entry = sortedPlayers.get(i);
            PlayerData data = entry.getValue();
            UUID uuid = entry.getKey();
            
            String playerName = Bukkit.getOfflinePlayer(uuid).getName();
            if (playerName == null) playerName = "未知玩家";
            
            String displayText = getEntryColorCode(i) + (i + 1) + ". " + playerName + ": " + data.getKills() + "击杀";
            if (displayText.length() > 40) {
                displayText = displayText.substring(0, 37) + "...";
            }
            
            Score score = objective.getScore(displayText);
            score.setScore(scoreValue--);
        }
        
        // 填充空行
        while (scoreValue > 1) {
            Score emptyScore = objective.getScore(repeatString(" ", scoreValue));
            emptyScore.setScore(scoreValue--);
        }
        
        // 添加底部边框
        Score bottomBorder = objective.getScore(getRandomBorder());
        bottomBorder.setScore(0);
        
        player.setScoreboard(scoreboard);
    }
    
    // 死亡排行榜
    private void setDeathsBoard(Player player) {
        Scoreboard scoreboard = Bukkit.getScoreboardManager().getNewScoreboard();
        Objective objective = scoreboard.registerNewObjective("deaths", Criteria.DUMMY, 
            Component.text(config.getString("scoreboard.titles.deaths", "死亡榜")));
        objective.setDisplaySlot(DisplaySlot.SIDEBAR);
        
        int displayPlayers = config.getInt("scoreboard.display_players", 10);
        List<Map.Entry<UUID, PlayerData>> sortedPlayers = dataManager.getAllPlayerData().entrySet().stream()
                .sorted(Map.Entry.<UUID, PlayerData>comparingByValue(Comparator.comparing(PlayerData::getDeaths)).reversed())
                .limit(displayPlayers)
                .collect(Collectors.toList());
        
        // 添加装饰边框
        Score topBorder = objective.getScore(getRandomBorder());
        topBorder.setScore(displayPlayers + 1);
        
        // 添加排行数据
        int scoreValue = displayPlayers;
        for (int i = 0; i < sortedPlayers.size(); i++) {
            Map.Entry<UUID, PlayerData> entry = sortedPlayers.get(i);
            PlayerData data = entry.getValue();
            UUID uuid = entry.getKey();
            
            String playerName = Bukkit.getOfflinePlayer(uuid).getName();
            if (playerName == null) playerName = "未知玩家";
            
            String displayText = getEntryColorCode(i) + (i + 1) + ". " + playerName + ": " + data.getDeaths() + "次";
            if (displayText.length() > 40) {
                displayText = displayText.substring(0, 37) + "...";
            }
            
            Score score = objective.getScore(displayText);
            score.setScore(scoreValue--);
        }
        
        // 填充空行
        while (scoreValue > 1) {
            Score emptyScore = objective.getScore(repeatString(" ", scoreValue));
            emptyScore.setScore(scoreValue--);
        }
        
        // 添加底部边框
        Score bottomBorder = objective.getScore(getRandomBorder());
        bottomBorder.setScore(0);
        
        player.setScoreboard(scoreboard);
    }
    
    // 经验排行榜
    private void setExperienceBoard(Player player) {
        Scoreboard scoreboard = Bukkit.getScoreboardManager().getNewScoreboard();
        Objective objective = scoreboard.registerNewObjective("experience", Criteria.DUMMY, 
            Component.text(config.getString("scoreboard.titles.experience", "经验榜")));
        objective.setDisplaySlot(DisplaySlot.SIDEBAR);
        
        int displayPlayers = config.getInt("scoreboard.display_players", 10);
        List<Map.Entry<UUID, PlayerData>> sortedPlayers = dataManager.getAllPlayerData().entrySet().stream()
                .sorted(Map.Entry.<UUID, PlayerData>comparingByValue(Comparator.comparing(PlayerData::getExperience)).reversed())
                .limit(displayPlayers)
                .collect(Collectors.toList());
        
        // 添加装饰边框
        Score topBorder = objective.getScore(getRandomBorder());
        topBorder.setScore(displayPlayers + 1);
        
        // 添加排行数据
        int scoreValue = displayPlayers;
        for (int i = 0; i < sortedPlayers.size(); i++) {
            Map.Entry<UUID, PlayerData> entry = sortedPlayers.get(i);
            PlayerData data = entry.getValue();
            UUID uuid = entry.getKey();
            
            String playerName = Bukkit.getOfflinePlayer(uuid).getName();
            if (playerName == null) playerName = "未知玩家";
            
            String displayText = getEntryColorCode(i) + (i + 1) + ". " + playerName + ": " + data.getExperience() + "经验";
            if (displayText.length() > 40) {
                displayText = displayText.substring(0, 37) + "...";
            }
            
            Score score = objective.getScore(displayText);
            score.setScore(scoreValue--);
        }
        
        // 填充空行
        while (scoreValue > 1) {
            Score emptyScore = objective.getScore(repeatString(" ", scoreValue));
            emptyScore.setScore(scoreValue--);
        }
        
        // 添加底部边框
        Score bottomBorder = objective.getScore(getRandomBorder());
        bottomBorder.setScore(0);
        
        player.setScoreboard(scoreboard);
    }
    
    // 根据排名获取不同颜色
    private NamedTextColor getEntryColor(int index) {
        if (index < COLORS.length) {
            return COLORS[index];
        }
        return NamedTextColor.WHITE;
    }
    
    // 根据排名获取颜色代码
    private String getEntryColorCode(int index) {
        if (index == 0) return "§c"; // 红色
        if (index == 1) return "§6"; // 金色
        if (index == 2) return "§e"; // 黄色
        if (index == 3) return "§a"; // 绿色
        if (index == 4) return "§b"; // 青色
        if (index == 5) return "§d"; // 淡紫色
        return "§f"; // 白色
    }
    
    // 获取随机边框装饰
    private String getRandomBorder() {
        String border = BORDERS[new Random().nextInt(BORDERS.length)];
        return "§6" + repeatString(border, 12) + "§r";
    }
    
    // 获取装饰过的标题
    private String getDecoratedTitle(String title) {
        Random random = new Random();
        NamedTextColor randomColor = COLORS[random.nextInt(COLORS.length)];
        String randomBorder = BORDERS[random.nextInt(BORDERS.length)];
        String colorCode = getColorCode(randomColor);
        
        return colorCode + randomBorder + " §b§l" + title + " " + colorCode + randomBorder + "§r";
    }
    
    // 获取颜色代码
    private String getColorCode(NamedTextColor color) {
        if (color == NamedTextColor.RED) return "§c";
        if (color == NamedTextColor.GOLD) return "§6";
        if (color == NamedTextColor.YELLOW) return "§e";
        if (color == NamedTextColor.GREEN) return "§a";
        if (color == NamedTextColor.AQUA) return "§b";
        if (color == NamedTextColor.LIGHT_PURPLE) return "§d";
        return "§f";
    }
} 